package com.gpframework.filter;

import com.google.api.client.repackaged.com.google.common.base.Joiner;
import com.gpframework.common.constant.BrandConstants;
import com.gpframework.common.constant.CacheConstants;
import com.gpframework.common.core.domain.entity.SysRole;
import com.gpframework.common.core.domain.entity.SysUser;
import com.gpframework.common.core.redis.RedisCache;
import com.gpframework.common.enums.YesNoEnum;
import com.gpframework.module.brand.service.IBrandStoreUserRelaService;
import com.gpframework.module.common.mapper.CommonWxUserMapper;
import com.gpframework.module.core.LoginUser;
import com.gpframework.module.module.domain.req.BrandStoreReq;
import com.gpframework.module.module.domain.vo.BrandInfoVo;
import com.gpframework.module.module.domain.vo.BrandStoreVo;
import com.gpframework.module.module.service.IBrandInfoService;
import com.gpframework.module.module.service.IBrandStoreService;
import com.gpframework.module.pay.utils.joinpay.sdk.utitls.StringUtil;
import com.gpframework.module.service.TokenService;
import com.gpframework.module.system.mapper.SysDeptMapper;
import com.gpframework.module.system.mapper.SysRoleMapper;
import com.gpframework.module.system.mapper.SysRoleStoreMapper;
import com.gpframework.module.system.mapper.SysUserMapper;
import com.gpframework.wrapper.RequestParameterWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;

/**
 * 参数过滤器(每次请求获取品牌id)
 *
 * @author zcl
 */
@WebFilter(urlPatterns = "/*", filterName = "ParameterRequestFilter")
public class ParameterRequestFilter implements Filter {
    private static final Logger log = LoggerFactory.getLogger(ParameterRequestFilter.class);

    @Autowired
    private TokenService tokenService;

    /**
     * 品牌系统角色与门店关联持久层接口
     */
    @Autowired
    private SysRoleStoreMapper sysRoleStoreMapper;

    /**
     * 品牌系统角色持久层接口
     */
    @Autowired
    private SysRoleMapper sysRoleMapper;

    /**
     * 品牌系统用户持久层接口
     */
    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 微信用户吃持久层接口
     */
    @Autowired
    private CommonWxUserMapper commonWxUserMapper;

    /**
     * 品牌系统部门持久层接口
     */
    @Autowired
    private SysDeptMapper sysDeptMapper;

    /**
     * 品牌业务层接口
     */
    @Autowired
    private IBrandInfoService brandInfoService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IBrandStoreService brandStoreService;

    @Autowired
    private IBrandStoreUserRelaService brandStoreUserRelaService;
    /**
     * 请求方式
     */
    private static final String GETTER_PREFIX = "GET";

    /**
     * 门店id参数常量
     */
    private static final String STORE_PARAMETER = "storeId";

    @Override
    public void init(FilterConfig filterConfig) {
    }

    /**
     * 不是管理员请求时添加品牌id作为参数
     *
     * @param servletRequest
     * @param servletResponse
     * @param chain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
//        ParameterRequestFilter request = new ParameterRequestFilter((HttpServletRequest) servletRequest);
        String contentType = request.getContentType();
        //获取当前用户
        try {
            if (!StringUtils.isEmpty(contentType) && contentType.startsWith("multipart/")) {
                chain.doFilter(servletRequest, servletResponse);
                return;
            }
            LoginUser loginUser = tokenService.getLoginUser(request);
            //是否有用户信息
            if (!StringUtils.isEmpty(loginUser) && !StringUtils.isEmpty(loginUser.getUser()) && !StringUtils.isEmpty(loginUser.getUser().getBrandId())) {
                //品牌id
                Long brandId = loginUser.getUser().getBrandId();
                List<Long> storeIdList;
                //不是品牌管理员且不是门店管理员查询用户关联门店
                if (!loginUser.getUser().whetherAdmin() && !StringUtils.isEmpty(loginUser.getUser().getStoreAdmin()) && YesNoEnum.YES.getKey().equals(loginUser.getUser().getStoreAdmin().toString())) {
                    storeIdList = brandStoreUserRelaService.getUserStoreIdList(loginUser.getUser().getWxUserId());
                } else {
                    //门店管理员获取门店id
                    storeIdList = new ArrayList<>();
                    storeIdList.add(loginUser.getUser().getStoreId());
                }
                // -------------------开始拦截请求参数-------------------
                //请求参数
/*                Map<String, Object> parameterMap;
                if (GETTER_PREFIX.equals(request.getMethod())) {
                    //get请求
                    parameterMap = JSONUtil.parseObj(ServletUtil.getParams(request));
                } else {
                    //post请求
                    parameterMap = JSONUtil.parseObj(request.getBody());
                }
                //获取门店id
                Object storeIdObj = parameterMap.get(STORE_PARAMETER);
                //没传门店id拦截报错
                if (StringUtils.isEmpty(storeIdObj) || "".equals(storeIdObj)) {
                    throw new BaseException("请选择门店");
                }*/
                // -------------------开始拦截请求参数-------------------
                Map<String, Object> params = new HashMap<>();
                if (StringUtils.isEmpty(brandId)) {
                    brandId = 0L;
                }
                params.put("brandId", brandId);
                //品牌信息
                BrandInfoVo brandInfoVo = brandInfoService.getBrandInfo(brandId);
                //品牌名称
                if (!StringUtils.isEmpty(brandInfoVo)) {
                    params.put("brandName", brandInfoVo.getBrandName());
                }
                BrandStoreReq brandStoreReq = new BrandStoreReq();
                brandStoreReq.setBrandId(brandId);
                brandStoreReq.setUserName(loginUser.getUsername());
                //门店信息
                BrandStoreVo storeVo = getBrandStore(brandStoreReq);
                //登录的用户id与用户名称
                if (!loginUser.getUser().whetherAdmin() && !StringUtils.isEmpty(loginUser.getUser().getWxUserId()) && StringUtils.isEmpty(storeVo)) {
                    params.put("loginWxUserId", loginUser.getUser().getWxUserId());
                    params.put("loginWxUserName", loginUser.getUser().getWxUserName());
                }
                //不是管理员且有门店id
                if (!loginUser.getUser().whetherAdmin() && !StringUtils.isEmpty(storeIdList) && storeIdList.size() > 0) {
                    params.put("storeIdList", Joiner.on(",").join(storeIdList));
                }
                //不是管理员且门店id只有一个
                if (!loginUser.getUser().whetherAdmin() && !StringUtils.isEmpty(storeIdList) && storeIdList.size() == 1) {
                    params.put("storeId", storeIdList.get(0));
                }
                // 不是管理员且没有门店id
                if (!loginUser.getUser().whetherAdmin() && (StringUtils.isEmpty(storeIdList) || storeIdList.size() <= 0)) {
                    params.put("storeId", 0);
                }
                //部门用户
/*                List<Long> deptUserList = deptUserList(loginUser.getUser());
                if (StringUtil.isNotEmpty(deptUserList)) {
                    params.put("deptUserList", Joiner.on(",").join(deptUserList));
                }*/
                //不是管理员且有部门用户id
/*                if (!loginUser.getUser().whetherAdmin() && !StringUtils.isEmpty(createByList) && createByList.size() > 0) {
                    params.put("createByList", Joiner.on(",").join(createByList));
                }*/
                //不是品牌管理员
                if (!loginUser.getUser().whetherAdmin()) {
                    //数据权限
                    String dataScope = allOrMy(loginUser.getUser());
                    params.put("roleDataScope", dataScope);
                    if (BrandConstants.DATA_SCOPE_THIS.equals(dataScope)) {
                        params.put("deptUserList", loginUser.getUser().getWxUserId());
                    }
                }
                //参数二：get请求添加参数
                RequestParameterWrapper requestParameterWrapper = new RequestParameterWrapper(request, params);
                //post请求添加参数
                requestParameterWrapper.setParamsMaps(params);
                chain.doFilter(requestParameterWrapper, servletResponse);
                return;
            }
            chain.doFilter(servletRequest, servletResponse);
        } catch (IOException e) {
            log.error("----------过滤时添加参数报错----------", e);
        } catch (ServletException e) {
            log.error("----------过滤时没有添加参数报错----------", e);
        }
    }

    @Override
    public void destroy() {
    }

    /**
     * 全部数据还是当前用户数据
     *
     * @param sysUser
     * @return
     */
    private String allOrMy(SysUser sysUser) {
        //获取用户角色
        List<SysRole> userRoleList = sysRoleMapper.getUserRoleList(sysUser.getBrandUserId());
        //所有数据权限
        String dataScope = BrandConstants.DATA_SCOPE_THIS;
        for (SysRole sysRole : userRoleList) {
            if (BrandConstants.DATA_SCOPE_ALL.equals(sysRole.getDataScope())) {
                dataScope = BrandConstants.DATA_SCOPE_ALL;
            }
        }
        return dataScope;
    }

    /**
     * 获取部门用户
     *
     * @return
     */
    private List<Long> deptUserList(SysUser sysUser) {
        //获取用户角色
        List<SysRole> userRoleList = sysRoleMapper.getUserRoleList(sysUser.getBrandUserId());
        //所有数据权限
        String dataScope = BrandConstants.DATA_SCOPE_THIS;
        //用户部门
        for (SysRole sysRole : userRoleList) {
            int i = dataScope.compareTo(sysRole.getDataScope());
            //所有数据
            if (sysRole.getDataScope().equals(BrandConstants.DATA_SCOPE_ALL) || BrandConstants.WE_CHAT_STORE_ADMIN.equals(sysRole.getRoleKey())) {
                return null;
            }
            //自定义数据权限
            if (i >= 0 && sysRole.getDataScope().equals(BrandConstants.DATA_SCOPE_CUSTOM)) {
                dataScope = BrandConstants.DATA_SCOPE_CUSTOM;
                i = sysRole.getDataScope().compareTo(dataScope);
            }
            //本部门
            if (i >= 0 && sysRole.getDataScope().equals(BrandConstants.DATA_SCOPE_THIS_DEPT)) {
                dataScope = BrandConstants.DATA_SCOPE_THIS_DEPT;
                i = sysRole.getDataScope().compareTo(dataScope);
            }
            //本部门及以下
            if (i >= 0 && sysRole.getDataScope().equals(BrandConstants.DATA_SCOPE_DEPT_LOWER)) {
                dataScope = BrandConstants.DATA_SCOPE_DEPT_LOWER;
            }

        }
        //仅自己数据直接返回
        if (dataScope.equals(BrandConstants.DATA_SCOPE_THIS)) {
            if (StringUtil.isEmpty(sysUser.getWxUserId())) {
                return null;
            }
            return Arrays.asList(sysUser.getWxUserId());
        }
        //本部门
        if (dataScope.equals(BrandConstants.DATA_SCOPE_THIS_DEPT)) {
            return commonWxUserMapper.findByBrandUserId(sysUser.getBrandUserId());
        }
        List<Long> deptUserList;
        //本部门及以下
        if (dataScope.equals(BrandConstants.DATA_SCOPE_DEPT_LOWER)) {
            deptUserList = new ArrayList<>();
            //当前用户部门id
            Long deptId = sysUser.getBrandDeptId();
            //部门id及下级部门id
            List<Long> deptIdList = sysDeptMapper.findByAncestors(deptId);
            deptIdList.add(deptId);
            //部门用户
            deptUserList = commonWxUserMapper.findByDeptList(deptIdList);
            return deptUserList;
        }
        //获取部门下用户id
        deptUserList = commonWxUserMapper.findByUserRoleList(userRoleList);
        deptUserList.add(sysUser.getBrandUserId());
        //部门数据权限
        return deptUserList;
    }

    /**
     * 获取门店信息
     *
     * @param storeReq
     * @return
     */
    private BrandStoreVo getBrandStore(BrandStoreReq storeReq) {
        //缓存key
        String key = CacheConstants.CACHE_STORE_INFO + storeReq.getBrandId() + "_" + storeReq.getUserName();
        //门店信息
        BrandStoreVo brandStoreVo = redisCache.getCacheObject(key);
        //信息不存在
        if (StringUtil.isEmpty(brandStoreVo)) {
            //删除缓存
            redisCache.deleteObject(key);
            //数据库获取门店信息
            brandStoreVo = brandStoreService.get(storeReq);
            //设置缓存信息
            redisCache.setCacheObject(key, brandStoreVo);
            //设置过期时间
            redisCache.expire(key, CacheConstants.CACHE_OVERDUE_AN_HOUR);
        }
        return brandStoreVo;
    }

}
